package com.loongtech.bi.manager.system;

import com.loongtech.bi.action.authManagement.ResultData;
import com.loongtech.bi.entity.POJO.Page;
import com.loongtech.bi.entity.system.EntityGameParam;
import com.loongtech.bi.entity.system.EntityGameParamType;
import com.loongtech.bi.support.CommonGameParam;
import com.loongtech.core.jpa.manager.ManagerQueryCacheBase;
import com.loongtech.core.util.RetCode;
import com.loongtech.core.util.Time;
import com.loongtech.core.util.Utils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

import static com.loongtech.bi.manager.system.SysProjectManager.projectIdNameMap;

@Service
public class GameParamConfigManager extends ManagerQueryCacheBase<EntityGameParam> {
    private static final long serialVersionUID = 2L;
    public static final String ALL_FLAT = "-99999";
    public static final int ALL_FLAT_INT = -99999;

    public static List<EntityGameParam> GAME_PARAM_LIST;  // EntityGameParam全表
    public static Map<Integer, Map<String, EntityGameParam>> TYPE2ID2GAMEPARAM_MAP;  // type=(id=EntityGameParam)
    public static Map<Integer, Map<String, EntityGameParam>> TYPE2NAME2GAMEPARAM_MAP;  // type=(name=EntityGameParam)

    public static Map<Integer, Map<String, String>> TYPE2ID2NAME_MAP;  // type=(id=name)
    public static Map<Integer, Map<String, String>> type2gameParamItmes;
    public static Map<Integer, Map<String, String>> type2gameParamItmesRevise;
    public static Map<Integer, String> CommonGameParamIdNameMap;
    @Resource
    private SyncInfoLogManager syncInfoLogManager;

    public void init() {
        GAME_PARAM_LIST = findByQuery("from EntityGameParam order by seq asc");
        List<Object> paramids = findByQuery("select paramid from EntityGameParam where paramtype = 1");

        if (GAME_PARAM_LIST == null || GAME_PARAM_LIST.size() <= 0 || paramids == null || paramids.size() <= 0) {
            for (CommonGameParam en : CommonGameParam.values()) {
                EntityGameParam t = new EntityGameParam();
                t.setGameId("0");
                t.setParamtype(1);
                t.setParamid(en.COMMONID + "");
                t.setParamname(en.COMMONID + "");
                persist(t);

                GAME_PARAM_LIST.add(t);
            }
        }
        if (paramids.size() < CommonGameParam.values().length) {
            List<Integer> tmpParamId = new ArrayList<>();
            for (Object i : paramids) {
                tmpParamId.add(Integer.parseInt(i.toString()));
            }

            for (CommonGameParam en : CommonGameParam.values()) {
                if (!tmpParamId.contains(en.COMMONID)) {
                    EntityGameParam t = new EntityGameParam();
                    t.setGameId("0");
                    t.setParamtype(1);
                    t.setParamid(en.COMMONID + "");
                    t.setParamname(en.COMMONID + "");
                    clear();
                    persist(t);

                    GAME_PARAM_LIST.add(t);
                }
            }
        }
        CommonGameParamIdNameMap = new HashMap<>();
        for (CommonGameParam c : CommonGameParam.values()) {
            CommonGameParamIdNameMap.put(c.COMMONID, c.DESC);
        }

        TYPE2ID2GAMEPARAM_MAP = new LinkedHashMap<>();
        TYPE2NAME2GAMEPARAM_MAP = new LinkedHashMap<>();
        TYPE2ID2NAME_MAP = new LinkedHashMap<>();
        type2gameParamItmes = new LinkedHashMap<>();
        type2gameParamItmesRevise = new LinkedHashMap<>();
        for (EntityGameParam e : GAME_PARAM_LIST) {
            int type = e.getParamtype();
            String id = e.getParamid();
            String value = e.getParamname();

            Map<String, EntityGameParam> tmp1 = TYPE2ID2GAMEPARAM_MAP.get(type);
            if (tmp1 == null) {
                tmp1 = new LinkedHashMap<>();
                TYPE2ID2GAMEPARAM_MAP.put(type, tmp1);
            }
            tmp1.put(id, e);

            Map<String, EntityGameParam> tmp2 = TYPE2NAME2GAMEPARAM_MAP.get(type);
            if (tmp2 == null) {
                tmp2 = new LinkedHashMap<>();
                TYPE2NAME2GAMEPARAM_MAP.put(type, tmp2);
            }
            tmp2.put(value, e);

            Map<String, String> tmp21 = TYPE2ID2NAME_MAP.get(type);
            if (tmp21 == null) {
                tmp21 = new HashMap<>();
                TYPE2ID2NAME_MAP.put(type, tmp21);
            }
            tmp21.put(id, value);

            Map<String, String> tmp3 = type2gameParamItmes.get(type);
            if (tmp3 == null) {
                tmp3 = new LinkedHashMap<>();
                tmp3.put("全部" + CommonGameParamIdNameMap.get(type), ALL_FLAT);
                type2gameParamItmes.put(type, tmp3);
            }
            tmp3.put(value, id);

            Map<String, String> tmp4 = type2gameParamItmesRevise.get(type);
            if (tmp4 == null) {
                tmp4 = new LinkedHashMap<>();
                tmp4.put(ALL_FLAT, "未知" + CommonGameParamIdNameMap.get(type));
                type2gameParamItmesRevise.put(type, tmp4);
            }
            tmp4.put(id + "", value);
        }
    }

    public Map<String, EntityGameParam> getIdGameParamMapByType(String gameId, int paramtype) {
        Map<String, EntityGameParam> result = new HashMap<>();

        List<EntityGameParam> te = findByQuery("from EntityGameParam where 1=1 and gameId = ? and paramtype = ? ", gameId, paramtype);
        if (te != null && te.size() > 0) {
            for (EntityGameParam e : te) {
                result.put(e.getParamid(), e);
            }
        }

        return result;
    }

    public List<EntityGameParam> getGameParamByEntity(EntityGameParam entity) {
        if (entity == null) {
            return null;
        }

        StringBuffer sql = new StringBuffer();
        sql.append("from EntityGameParam where 1=1 and paramtype = ");
        sql.append(entity.getParamtype());

        if (entity.getParamid() != null && !"".equals(entity.getParamid().trim())) {
            sql.append(" and paramid = '");
            sql.append(entity.getParamid());
            sql.append("' ");
        }

        if (entity.getParamname() != null && !"".equals(entity.getParamname().trim())) {
            sql.append(" and paramname = '");
            sql.append(entity.getParamname());
            sql.append("' ");
        }

        sql.append(" order by paramtype,paramid");

        return findByQuery(sql.toString());
    }

    /**
     * 能否添加（id和name没重复）
     *
     * @param e
     * @return
     */
    public static boolean canAdd(EntityGameParam e, boolean isAdd) {
        if (TYPE2ID2GAMEPARAM_MAP == null || TYPE2ID2GAMEPARAM_MAP.get(e.getParamtype()) == null || TYPE2NAME2GAMEPARAM_MAP == null || TYPE2NAME2GAMEPARAM_MAP.get(e.getParamtype()) == null) {
            return true;
        }

        // 副本类型、任务类型、事件类型，paramname可以重复
        if (e.getParamtype() == getParamType(CommonGameParam.INSTANCE_TYPE)
                || e.getParamtype() == getParamType(CommonGameParam.TASK_TYPE)
                || e.getParamtype() == getParamType(CommonGameParam.EVENT_TYPE)) {
            return isAdd ? (!TYPE2ID2GAMEPARAM_MAP.get(e.getParamtype()).containsKey(e.getParamid())) : true;
        } else { // TODO
            //return isAdd ? (!TYPE2ID2GAMEPARAM_MAP.get(e.getParamtype()).containsKey(e.getParamid()) && !TYPE2NAME2GAMEPARAM_MAP.get(e.getParamtype()).containsKey(e.getParamname())) : !TYPE2NAME2GAMEPARAM_MAP.get(e.getParamtype()).containsKey(e.getParamname());
            //return isAdd ? (!TYPE2ID2GAMEPARAM_MAP.get(e.getParamtype()).containsKey(e.getParamid()) && !TYPE2NAME2GAMEPARAM_MAP.get(e.getParamtype()).containsKey(e.getParamname())) : true;
            return isAdd ? (!TYPE2ID2GAMEPARAM_MAP.get(e.getParamtype()).containsKey(e.getParamid())) : true;

        }
    }

    /**
     * 能否添加（id和name没重复）
     *
     * @param e
     * @return
     */
    public boolean canAddNew(EntityGameParam e) {
        //同游戏同参数类型下paramid不重复
        List<EntityGameParam> res1 = findByQuery("from EntityGameParam where paramtype = ? and paramid = ?", e.getParamtype(), e.getParamid());
        HashSet<String> set = new HashSet<>();
        for (EntityGameParam param : res1) {
            String[] gameIds = param.getGameId().split(",");
            set.addAll(Arrays.asList(gameIds));
        }
        String[] ids = e.getGameId().split(",");
        boolean flag = true;
        for (String id : ids) {
            if (set.contains(id)) {
                flag = false;
                break;
            }
        }
        return flag;
//        // 副本类型、任务类型、事件类型，paramname可以重复，其他不能
//        List<EntityGameParam> res2 = getByQuery("from EntityGameParam where paramtype = ? and paramname = ? and paramtype not in (?,?,?)", e.getParamtype(), e.getParamname(), CommonGameParam.INSTANCE_TYPE.COMMONID, CommonGameParam.TASK_TYPE.COMMONID, CommonGameParam.EVENT_TYPE.COMMONID);
//        HashSet<String> set2 = new HashSet<>();
//        for (EntityGameParam param : res2) {
//            String[] gameIds = param.getGameId().split(",");
//            set2.addAll(Arrays.asList(gameIds));
//        }
//        return !(res1 != null || res2 != null);
    }

    public static String getNameByTypeAndId(int type, int id) {
        return TYPE2ID2NAME_MAP.get(type).get(id) == null ? id + "" : TYPE2ID2NAME_MAP.get(type).get(id);
    }

    /**
     * 根据CommonGameParam找到对应的游戏参数Type
     *
     * @param e
     * @return
     */
    public static int getParamType(CommonGameParam e) {
        return Integer.parseInt(TYPE2ID2NAME_MAP.get(1).get(e.COMMONID + ""));
    }

    public static boolean isConfiged(CommonGameParam e) {
        return type2gameParamItmes.get(getParamType(e)) != null;
    }

    @SuppressWarnings("serial")
    public static Map<String, String> getItems(CommonGameParam e) {
        return !isConfiged(e) ? new HashMap<String, String>() {{
            put("全部", ALL_FLAT);
            put("请配置", "-11111");
        }} : type2gameParamItmes.get(getParamType(e));
    }

    @SuppressWarnings("serial")
    public static Map<String, String> getItemsRevise(CommonGameParam e) {
        return !isConfiged(e) ? new HashMap<String, String>() {{
            put(ALL_FLAT, "未知");
            put("-11111", "请配置");
        }} : type2gameParamItmesRevise.get(getParamType(e));
    }

    /**
    去除-99999
     */
    public static Map<String, String> getItemsRevise2(CommonGameParam e) {
        Map<String, String> map = new HashMap<>(16);
        if (!isConfiged(e)) {
            new HashMap<String, String>() {{
                put(ALL_FLAT, "未知");
                put("-11111", "请配置");
            }};
        } else {
            map = type2gameParamItmesRevise.get(getParamType(e));
            map.remove(GameParamConfigManager.ALL_FLAT);
        }
        return map;
    }


    /**
     * 查询任务(springmvc)
     */
    public Page<List<EntityGameParam>> queryByCriteria(Integer curPage, Integer pageSize, EntityGameParam entity) {
        List<Object> cons = new ArrayList<>();
        StringBuilder hql = new StringBuilder(" from EntityGameParam e where 1=1 ");
        if (entity.getGameId() != null) {
            hql.append(" and e.gameId like ?");
            cons.add("%" + entity.getGameId() + "%");
        }
        if (!Utils.isEmptyStr(entity.getParamid())) {
            hql.append(" and e.paramid = ?");
            cons.add(entity.getParamid());
        }
        if (!Utils.isEmptyStr(entity.getParamname())) {
            hql.append(" and e.paramname like ?");
            cons.add("%" + entity.getParamname() + "%");
        }
        if (entity.getParamtype() != null) {
            hql.append(" and e.paramtype = ?");
            cons.add(entity.getParamtype());
        }
        hql.append(" order by e.gameId desc,e.id");
        Integer totalSize = countNum(hql.toString(), cons.toArray());
        //数据
        List<EntityGameParam> list = findByQuery((curPage - 1) * pageSize, pageSize, hql.toString(), cons.toArray());
        List<EntityGameParamType> clist = findByQuery("from EntityGameParamType order by id");
        Map<Integer, String> map = new HashMap<>();
        if (clist != null && clist.size() > 0) {
            for (EntityGameParamType entityGameParamType : clist) {
                map.put(entityGameParamType.getId(), entityGameParamType.getName());
            }
        }
        if (list != null && list.size() > 0) {
            for (EntityGameParam param : list) {
                Integer s = param.getParamtype();
                param.setParamtypeName(map.get(s));

                String gameid = param.getGameId();
                for (Map.Entry<String, String> entry : projectIdNameMap.entrySet()) {
                    gameid = gameid.replace(entry.getKey() + ",", entry.getValue() + ",");
                }
                param.setGameName(gameid);
            }
        }
        return new Page<>(list, totalSize, curPage, pageSize);
    }

    //根据参数类型和参数id删除
    public ResultData<String> removeByEntity(Integer id) {
        try {
            EntityGameParam cur = get(id);
            if (cur != null) {
                removeById(id);
                // 插入同步表
                Integer paramtype = cur.getParamtype();
                String paramid = cur.getParamid();
                for (String gid : cur.getGameId().split(",")) {
                    syncInfoLogManager.add(gid, "delete from bi_game_param where paramtype = " + paramtype + " and paramid = " + paramid);
                }
                init();
                return ResultData.success();
            } else {
                init();
                return new ResultData<>(RetCode.eNotExistGourp.getErrorcode(), RetCode.eNotExistGourp.getErrorMsg());
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            return ResultData.otherException();
        }
    }

    public ResultData<String> modifyByEntity(EntityGameParam entity) {
        try {
            EntityGameParam cur = get(entity.getId());
            if (cur != null) {
                merge(entity);

                String gameIds = entity.getGameId();
                // 删老数据
//                List<EntityGameParam> params = findByQuery("from EntityGameParam where 1=1 and paramtype = ? and paramid = ?", entity.getParamtype(), entity.getParamid());
//                if (params != null && params.size() > 0) {
//                    for (EntityGameParam param : params) {
//                        String gids = param.getGameId();
//                        if (gids.equals(gameIds)) {
//                            remove(param);
//                        } else {
//                            for (String gid : gameIds.split(",")) {
//                                if (gids.equals(gid + ",")) {
//                                    remove(param);
//                                } else {
//                                    if (gids.contains(gid + ",")) {
//                                        gids = gids.replace(gid + ",", "");
//                                        param.setGameId(gids);
//                                        merge(param);
//                                    }
//                                }
//                            }
//                        }
//                    }
//                }
//                // 插新数据
//                persist(entity);
//                insertSQLEnd.append("(").append("'").append(gameIds).append("',").append(entity.getParamtype()).append(",'").append(entity.getParamid()).append("','").append(entity.getParamname()).append("',").append(entity.getSeq()).append(",").append(Time.currentTime()).append("),");
//
//                String dsql = "delete from bi_game_param where paramtype = " + entity.getParamtype() + " and paramid = " + entity.getParamid();
//                String isql = "insert into bi_game_param(gameId,paramtype,paramid,paramname,seq,updateAt) values" + insertSQLEnd.substring(0, insertSQLEnd.length() - 1);

                // 插入同步表
                StringBuilder excuteSql = new StringBuilder();
                excuteSql.append("update bi_game_param set paramname = '").append(entity.getParamname()).append("',seq = ").append(entity.getSeq()).append(",updateAt = ").append(Time.currentTime()).append(" where paramtype = ").append(entity.getParamtype()).append(" and paramid = '" ).append(entity.getParamid()).append("'");
                for (String gid : gameIds.split(",")) {
                    syncInfoLogManager.add(gid, excuteSql.toString());
                }
                init();
                return ResultData.success();
            } else {
                return new ResultData<>(RetCode.eNotExistGourp.getErrorcode(), RetCode.eNotExistGourp.getErrorMsg());
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            return ResultData.otherException();
        }
    }
}
